#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/un.h> 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h> 
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <ctype.h>


#include "constantes.h"
#include "estructuras.h"
#include "configuracion.h"
#include "sockets.h"
#include "CSCAN.h"
#include "estadisticas.h"
#include "commands.h"
#include "NIPC.h"
#include "consola.h"

int numoletra(char letra);
void intacad ( int n , char* cadena);
char* Generar_Desc_ID ( void );

int Sock_consola;
extern ListConfig * listaConfig;

int main(){
	
    char *buffer;		
    int i, respuesta, iEnv;
    int len;
    struct sockaddr_un remote;
	char* cadena;
	char input[100];
	InfoIPC rInfoIPC;
	
	listaConfig = NULL;
	cargarConfig(); 	
	
	
	printf("\nCONSOLA INICIALIZADA\n");
	Sock_consola=crearSocket(AF_UNIX);
	printf("CONECTANDO CON EL PPD...\n");
	system("clear");
	remote.sun_family = AF_UNIX;
	strcpy(remote.sun_path, "sock_consola");
	len = strlen(remote.sun_path) + sizeof(remote.sun_family);
	if (connect(Sock_consola, (struct sockaddr *)&remote, len) == -1) {
        perror("connect");
        exit(1);
	}	
	printf("Conexion establecida entre Consola y PPD\n\n"); 
	   
	printf("MENU CONSOLA PPD \n");
	printf("------------------\n");
	printf("1)trace S1 [S2 S3 S4 S5] \n");
	printf("2)info \n");
	printf("3)clean S1 S2 \n");
	printf("\n");
   
	t_commands *cmd = (t_commands *)commands_createWithConext(NULL, ' ', '\n', ' ');
	commands_add(cmd, "info", info);
	commands_add(cmd, "clean", clean);
	commands_add(cmd, "trace", trace);
	
	while (1) { 
		printf("\nIngrese comando:  ");
		fflush(stdin);
        fgets(input, 100,stdin);
		commands_parser(cmd,input);
	}
	commands_destroy(cmd);
    return 1;

}



void info(void *context, t_array *args) {
	
	InfoIPC rInfoIPC;
	
	rInfoIPC.payLoadLength=5;
	generarStructIPC("nada",INFO,&rInfoIPC);
	enviarIPC(Sock_consola,&rInfoIPC);
	
	free(rInfoIPC.payload);
}


void clean(void *context, t_array *args) {
	
	InfoIPC rInfoIPC;
	
	if (args == NULL || array_size(args) != 2) {
		printf("clean <sector inicial> <sector final>\n");
		return;
    }	

	char *enviar=(char*)malloc(strlen(array_get(args, 0))+ 1 + strlen(array_get(args, 1)) +1);
	strcpy(enviar,array_get(args, 0));
	strcat(enviar," ");
	strcat(enviar,array_get(args, 1));
	
	rInfoIPC.payLoadLength=strlen(enviar)+1;
	generarStructIPC(enviar,CLEAN,&rInfoIPC);
	enviarIPC(Sock_consola,&rInfoIPC);
	
	free(rInfoIPC.payload);
	free(enviar);
}



void trace(void *context, t_array *args) {
	
	InfoIPC rInfoIPC;
	int i;
	
	if (args == NULL || array_size(args) > 5) {
		printf("trace [lista sectores]\n");
		return;
    }
	
	char *enviar=(char*)malloc(50);
	
	strcpy(enviar,array_get(args, 0));
	strcat(enviar," ");
	
	for (i = 1; i < array_size(args); i++) {
		strcat(enviar,array_get(args, i));
		strcat(enviar," ");
    }
	
	if(array_size(args)<5){
		while(i <5) {
			strcat(enviar,"-1");
			strcat(enviar," ");
			i++;
		}
	}
	
	
	rInfoIPC.payLoadLength=strlen(enviar)+1;
	generarStructIPC(enviar,TRACE,&rInfoIPC);
	printf("Antes de enviar trace \n");
	enviarIPC(Sock_consola,&rInfoIPC);
	

	free(rInfoIPC.payload);
	free(enviar);
	
}



int numoletra(char letra){
      
     if((isdigit(letra))||(isalpha(letra))) 
      return 0;
     
     return 1;   
}

void intacad ( int n , char* cadena)
{	
    int j=0;
    int i=0;
	char aux;

	do
    {
    cadena[i] = (n % 10) + '0';    
	n=n/10;
	i++;
	}while (n > 0);

    cadena[i] = '\0';
    i--;

	while(i>j)
	{
    aux=cadena[i];
	cadena[i]=cadena[j];
	cadena[j]=aux;
	i--;
	j++;
	}

}

char* Generar_Desc_ID ( void )
{
	static char ID [ 16 ] = "\0"; 
	unsigned int i;
	time_t tiempo;
	
	tiempo = time ( NULL );
	srand ((unsigned int) tiempo );
	for( i = 0 ; i < 16 ; i++ )
	{
		if((rand ( ) % 2) == 0)
		{
			ID [ i ] = 97 + rand ( ) % 25;
		}
		else
		{
			ID [ i ] = 48 + rand ( ) % 10;
		}
	}
   
	return ID;
}
